{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy\n",
    "from itertools import chain, combinations\n",
    "from fractions import Fraction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def powerset(iterable):\n",
    "    s = list(iterable)\n",
    "    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shap_coefficients(n):\n",
    "    # Create a set with all players except player 1\n",
    "    N = np.arange(n - 1) + 2\n",
    "    coeff_dict = {}\n",
    "    for S in powerset(N):\n",
    "        coeff_dict[tuple(S)] = Fraction(np.math.factorial(len(S)) * \\\n",
    "                                   np.math.factorial(n - len(S) + 1),\n",
    "                                   np.math.factorial(n))\n",
    "        coeff_dict[tuple(S + (1,))] = Fraction(-np.math.factorial(len(S)) * \\\n",
    "                                   np.math.factorial(n - len(S) + 1),\n",
    "                                   np.math.factorial(n))\n",
    "    return coeff_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shap_coefficients_mobius(n):\n",
    "    N = np.arange(n - 1) + 2\n",
    "    coeff_dict = {}\n",
    "    for S in powerset(N):\n",
    "        coeff_dict[tuple(S + (1,))] = Fraction(1, len(S) + 1)\n",
    "    return coeff_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sum_interaction_coefficients(n):\n",
    "    N = np.arange(n - 1) + 2\n",
    "    coeff_dict = {}\n",
    "    for K in powerset(N):\n",
    "        coeff = 0\n",
    "        for S in powerset(K):\n",
    "            if len(S) == 0:\n",
    "                continue\n",
    "            num = int(np.math.pow(-1, len(S) + 1))\n",
    "            denom = (len(K) - len(S) + 1) * \\\n",
    "                              np.math.factorial(len(S) + 1)\n",
    "            coeff += Fraction(num, denom)\n",
    "        coeff_dict[tuple(S + (1,))] = coeff\n",
    "    return coeff_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "def key_to_tabs(n, key):\n",
    "    div = 3\n",
    "    if n > 3:\n",
    "        div = 3\n",
    "    \n",
    "    max_tabs = int(n / div) + 1\n",
    "    return '\\t' * (max_tabs - int(len(key) / div))\n",
    "    \n",
    "def print_coeff_dict(coeff_dict, n):\n",
    "    for key in coeff_dict:\n",
    "        print('{}:{}{}'.format(key, key_to_tabs(n, key), coeff_dict[key]))\n",
    "        \n",
    "def print_diff_dict(d1, d2, n):\n",
    "    for key in d1:\n",
    "        print('{}:{}{}'.format(key, key_to_tabs(n, key), d1[key] - d2[key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1,):\t\t1\n",
      "(2, 1):\t\t0\n",
      "(3, 1):\t\t0\n",
      "(4, 1):\t\t0\n",
      "(2, 3, 1):\t0\n",
      "(2, 4, 1):\t0\n",
      "(3, 4, 1):\t0\n",
      "(2, 3, 4, 1):\t-1/24\n"
     ]
    }
   ],
   "source": [
    "n = 4\n",
    "# print('======Shapley Mobius Coefficients=======:')\n",
    "shap_coeff_dict = shap_coefficients_mobius(n)\n",
    "# print_coeff_dict(shap_coeff_dict, n)\n",
    "# print('======Interaction Mobius Coefficients=======:')\n",
    "inter_coeff_dict = sum_interaction_coefficients(n)\n",
    "# print_coeff_dict(inter_coeff_dict, n)\n",
    "print_diff_dict(shap_coeff_dict, inter_coeff_dict, n)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
